function drAbreFichero (rutaFichero,idVentana,titulo,url,ancho,alto,posicion,testigo,elOnClose,urlAyuda)	{
	/*TO-DO: parametro url*/
	var extension=drExtraeExtension(rutaFichero);
	if (drDesktopWin.oTipos[extension] ==null)	{
		alert("La extensi�n '"+extension+" no est� asociada a ninguna aplicaci�n.");
		return;
		}
	var idAplicacion=drDesktopWin.oTipos[extension].aplicacion
	var oAplicacion=drDesktopWin.oAplicaciones[idAplicacion]
	var oMotores=drDesktopWin.oMotores
	var laUrlFinal=oAplicacion.url+"?file="+escape(rutaFichero)
	if (oAplicacion.motor!=null)	{
		//Esto habr�a que hacerlo pasar por un punto �nico (por el usuario, etc ?)
		laUrlFinal=oMotores[oAplicacion.motor].url
		}
	if (laUrlFinal!=null)	{
		if (oAplicacion.unica!=null && (oAplicacion.unica=="S"||oAplicacion.unica=="s"||oAplicacion.unica=="true") && oAplicacion.idVentana==null)
			oAplicacion.idVentana=dameIdQueNoColisione()
		//Tomo los valores de la aplicaci�n
		ancho=(ancho==null)?oAplicacion.ancho:ancho;
		alto=(alto==null)?oAplicacion.alto:alto;	
		posicion=(posicion==null)?oAplicacion.posicion:posicion;	
		testigo=(testigo==null)?oAplicacion.testigo:testigo;
		idVentana=(idVentana==null)?oAplicacion.idVentana:idVentana;
		elOnClose=(elOnClose==null)?oAplicacion.elOnClose:elOnClose;	
		//url=(url==null)?oAplicacion.url:url;	
		titulo=(titulo==null)?oAplicacion.titulo:titulo;		
		urlAyuda=(urlAyuda==null)?oAplicacion.urlAyuda:urlAyuda;	
		
		//Aplicamos los par�metros
		if (oAplicacion.parametros!=null && oAplicacion.parametros.length>0)	{
			laUrlFinal=laUrlFinal+"?"
			for (var r=0;r<oAplicacion.parametros.length;r++)	{
				if (r>0)
					laUrlFinal=laUrlFinal+"&"
				laUrlFinal=laUrlFinal+escape(oAplicacion.parametros[r].nombre)+"="+escape(oAplicacion.parametros[r].valor)
				}
			}
			
		return drAbreVentana(idVentana,titulo,laUrlFinal,ancho,alto,posicion,testigo,elOnClose,urlAyuda)	/*TO-DO: retorne el id de la ventana*/
		}
	else if (oAplicacion.js!=null)	{
		eval(oAplicacion.js)
		}
	}

function drAbreAplicacion(idAplicacion,idVentana,titulo,url,ancho,alto,posicion,testigo,elOnClose,urlAyuda)	{
	/*TO-DO: parametro url*/
	var oAplicacion=drDesktopWin.oAplicaciones[idAplicacion]
	var oMotores=drDesktopWin.oMotores
	var laUrlFinal=oAplicacion.url
	if (oAplicacion.motor!=null)	{
		//Esto habr�a que hacerlo pasar por un punto �nico (por el usuario, etc ?)
		laUrlFinal=oMotores[oAplicacion.motor].url
		}
	if (laUrlFinal!=null)	{
		if (oAplicacion.unica!=null && (oAplicacion.unica=="S"||oAplicacion.unica=="s"||oAplicacion.unica=="true") && oAplicacion.idVentana==null)
			oAplicacion.idVentana=dameIdQueNoColisione()
		//Tomo los valores de la aplicaci�n
		ancho=(ancho==null)?oAplicacion.ancho:ancho;
		alto=(alto==null)?oAplicacion.alto:alto;	
		posicion=(posicion==null)?oAplicacion.posicion:posicion;	
		testigo=(testigo==null)?oAplicacion.testigo:testigo;
		idVentana=(idVentana==null)?oAplicacion.idVentana:idVentana;
		elOnClose=(elOnClose==null)?oAplicacion.elOnClose:elOnClose;	
		//url=(url==null)?oAplicacion.url:url;	
		titulo=(titulo==null)?oAplicacion.titulo:titulo;		
		urlAyuda=(urlAyuda==null)?oAplicacion.urlAyuda:urlAyuda;	
		
		//Aplicamos los par�metros
		if (oAplicacion.parametros!=null && oAplicacion.parametros.length>0)	{
			laUrlFinal=laUrlFinal+"?"
			for (var r=0;r<oAplicacion.parametros.length;r++)	{
				if (r>0)
					laUrlFinal=laUrlFinal+"&"
				laUrlFinal=laUrlFinal+escape(oAplicacion.parametros[r].nombre)+"="+escape(oAplicacion.parametros[r].valor)
				}
			}
			
		return drAbreVentana(idVentana,titulo,laUrlFinal,ancho,alto,posicion,testigo,elOnClose,urlAyuda)	/*TO-DO: retorne el id de la ventana*/
		}
	else if (oAplicacion.js!=null)	{
		eval(oAplicacion.js)
		}
	}

function drCierraVentana(id)	{
	var objxDT=drDesktopWin.xDT
	objxDT.deleteWindow(id);
	}

/* [+] drAbreVentana */
/* 		Para hacer multiples ventanas hay que poner id a null y el sistema les da un id distinto a cada una */
function drAbreVentana(id,titulo,url,ancho,alto,posicion,testigo,elOnClose,urlAyuda)	{
	if (id==null)
		id=dameIdQueNoColisione()
	DruidaAbreVentana(id,titulo,url,ancho,alto,posicion,testigo,null,elOnClose,urlAyuda)
	return id;
	}

/* [+] drDameMiId */	
function drDameMiId()	{
	return DruidaDameMiIdVentana()
	}
	
/* [+] drDameIdVentanas */
function drDameIdVentanas()	{
	return DruidaVentanasId()
	}
	
	
	
	
	
var drDesktopWin = window.top.f1

/* + DruidaAbreVentana */
//function DruidaAbreVentana() {
function DruidaAbreVentana(id,titulo,url,ancho,alto,posicion,testigo,idPadre,elOnClose,urlAyuda) {
	/*if (sePuedeCerrar==null) 
		sePuedeCerrar=true; // Valor por defecto 
	if (esMultiple==null)
		esMultiple=false // Valor por defecto */
	//Solo puede existir una ventana por cada id
	if (ancho==null)
		ancho=300
	if (alto==null)
		alto=200		
	var objxDT=drDesktopWin.xDT
	win = objxDT.addWindow(id,titulo,200,100,posicion)//,skin
	objxDT.resizeWindow(id,ancho,alto)
	objxDT.window.onClose(id,"DruidaDesregistraVentana(wName);var result=DruidaVerificaOnWindowClose(wName);result");
	objxDT.url(id,url);
	var elIFRAME=DruidaDameIframeVentana(id)	
	//elIFRAME es el IFRAME donde cargo la URL
	elIFRAME.drIdVentana=id
	//elIFRAME.drNombreVentana=nombre		
	objxDT.prop(id,"drUrlInfo",urlAyuda)
	if (testigo!=null)	{
		elIFRAME.testigo=testigo
		elIFRAME.onreadystatechange=function(){
			if (this.readyState=="complete"){
				var elWindow=this.contentWindow
				if (elWindow.DrDesktopTomaTestigo!=null &&  typeof elWindow.DrDesktopTomaTestigo == 'function')
					elWindow.DrDesktopTomaTestigo(this.testigo)
				}
			}
		}
	objxDT.show(id);
	/*	with (document.getElementsByName('winleft_'+id)[0].cbe) {
      addEventListener('drag');
   }*/
	
	DruidaRegistraVentana(id,idPadre)
	}

function DruidaRegeneraVentana(id,titulo,url,ancho,alto,posicion,testigo,idPadre,urlAyuda)	{
	//Utilizada por el desktop para generar las ventanas al iniciar
	//Funci�n creada para mejorar el futuro desarrollo / mantenimiento
	DruidaAbreVentana(id,titulo,url,ancho,alto,posicion,testigo,idPadre,null,urlAyuda)
	}
	
function dameIdQueNoColisione()	{ 
	var losID="|"+ DruidaVentanasId().join("|") +"|"
	var nuevoId="drWin"+Math.round(Math.random(33)*100000000)
	while (losID.indexOf("|"+nuevoId+"|")!=-1)	
		nuevoId="drWin"+Math.round(Math.random(33)*100000000)
	return nuevoId
	}	

function DruidaDameMiIdVentana()	{
	//[ ] TO-DO: que pille esto aunque sea en un frame dentro de este frame ...
	if (frameElement!=null && frameElement.drIdVentana!=null)
		return frameElement.drIdVentana
	return null	
	}
	
function DruidaDameWindowVentana(id)	{
	return DruidaDameIframeVentana(id).contentWindow
	}
	
function DruidaDameIframeVentana(id)	{
	//Esto me puede dar permiso denegado:  document.getElementsByName('xDTiF_test')[0].contentWindow.location.href
	return drDesktopWin.document.getElementsByName('xDTiF_'+id)[0]
	}	
	
function DruidaRegistraVentana(id,idPadre)	{
	//si idPadre es null lo calcula
	if (drDesktopWin.oVentanas==null)	
		drDesktopWin.oVentanas=new clDrVentanas()
	//alert("se abre ID: "+id+ " desde ID: "+ DruidaDameMiIdVentana())
	if (idPadre!=null)
		drDesktopWin.oVentanas.mete(id, idPadre);
	else
		drDesktopWin.oVentanas.mete(id, DruidaDameMiIdVentana());	
	}

function DruidaDesregistraVentana(id)	{
	drDesktopWin.oVentanas.saca(id);
	return true;
	}

function DruidaVerificaOnWindowClose(id)	{
	var elWindow=DruidaDameIframeVentana(id).contentWindow
	if (elWindow.DrDesktopOnWindowClose!=null &&  typeof elWindow.DrDesktopOnWindowClose == 'function')
		return elWindow.DrDesktopOnWindowClose()
	else
		return true
	}

function DruidaVentanasId()	{
	//Retornamos las ventanas que existen (solo los ID)...
	if (drDesktopWin.oVentanas==null)
		return []
	var arrObj=drDesktopWin.oVentanas.getLista();
	var arrId=[]
	for (var r=0;r<arrObj.length; r++)
		arrId[arrId.length]=arrObj[r].id
	return arrId
	}	
	
function DruidaVentanas()	{
	//Retornamos las ventanas que existen ...
	if (drDesktopWin.oVentanas==null)
		return []
	return drDesktopWin.oVentanas.getLista();
	}		
	
function cierraSesionVentanas(){
	window.ventanasSinEstado=[]
	var ventanas=DruidaVentanas();
	for (var r=0; r<ventanas.length; r++)	{
		ventanas[r].ancho = drDesktopWin.xDT.prop(ventanas[r].id,'wWidth')
		ventanas[r].alto = drDesktopWin.xDT.prop(ventanas[r].id,'wHeight')
		ventanas[r].posicion = drDesktopWin.xDT.prop(ventanas[r].id,'wX')+","+drDesktopWin.xDT.prop(ventanas[r].id,'wY') //No uso wPos porque al regenerar puede que no existan las ventanas desde las que te colocaste con un offset
		ventanas[r].url = drDesktopWin.xDT.prop(ventanas[r].id,'wUrl')
		ventanas[r].titulo = drDesktopWin.xDT.prop(ventanas[r].id,'wTitle')
		ventanas[r].urlAyuda = drDesktopWin.xDT.prop(ventanas[r].id,'drUrlInfo')		
		//Pero lo necesito para llamar a su evento si lo hay ...
		var ventana=DruidaDameWindowVentana(ventanas[r].id)
		if (ventana.DrDesktopDameTestigo && isFunction(ventana.DrDesktopDameTestigo))
			ventanas[r].testigo=ventana.DrDesktopDameTestigo() //HA DE DEVOLVER UN STRING (algo mas complejo --> que usen JSON)
		else	{
			ventanas[r].testigo=null
			ventanasSinEstado[ventanasSinEstado.length]=ventanas[r].titulo
			}
		}
	document.fcerrar.ventanas.value=objetoAJSONString(ventanas)
	if (window.ventanasSinEstado!=null && window.ventanasSinEstado.length>0)	{
		if (ventanasSinEstado.length>1)	{
			if (oDesktopConfig.animacionesActivas)
				drOscureceFondo(true)			
			//Hay 1 ventana que se guardar� como <span class="drTextoResaltado" title="Aplicaciones sin estado: Al abrir el escritorio estas ventanas se recuperar�n tal y como estaban al abrirse y sin tener en cuenta la posible evoluci�n posterior de su contenido"> aplicacion sin estado</span>:  Frases ingeniosas
			drAlertSistema ("Hay "+ventanasSinEstado.length+' ventanas que se guardar�n como <span class="drTextoResaltado" title="Aplicaciones sin estado: Al abrir el escritorio estas ventanas se recuperar�n tal y como estaban al abrirse y sin tener en cuenta la posible evoluci�n posterior de su contenido"> aplicaciones sin estado</span>: '+ventanasSinEstado.join (", ") )
			}
		if (ventanasSinEstado.length==1)	{
			if (window.animacionesActivas)
				drOscureceFondo(true)			
			//Hay 1 ventana que se guardar� como <span class="drTextoResaltado" title="Aplicaciones sin estado: Al abrir el escritorio estas ventanas se recuperar�n tal y como estaban al abrirse y sin tener en cuenta la posible evoluci�n posterior de su contenido"> aplicacion sin estado</span>:  Frases ingeniosas
			drAlertSistema ('Hay 1 ventana que se guardar� como <span class="drTextoResaltado" title="Aplicaciones sin estado: Al abrir el escritorio estas ventanas se recuperar�n tal y como estaban al abrirse y sin tener en cuenta la posible evoluci�n posterior de su contenido"> aplicacion sin estado</span>: '+ventanasSinEstado[0])
			}
		}	
	}


function DruidaSonVentanasFamilia(id1,id2)	{
	//Busco en la jerarquia para ver si son ASCENDENTES O DESCENDIENTES un de la otra (hermanos no se consideran)
	if (drDesktopWin.oVentanas==null)
		return false
	return drDesktopWin.oVentanas.sonFamilia(id1,id2)
	}

function isFunction(a)  {      
	return typeof a == 'function'; 
	}	


//  ************************ OBJETOS
		
function clDrVentanas()	{//clase del Objeto controlador de las ventanas que existen
	//Restricci�n: con el mismo ID solo debe existir una ventana ... TO-DO: varios

	this.lventanas=[]
	
	/* + mete(id) */
	this.mete=function (id, idPadre)	{
		//idpadre puede ser null
		var nuevaVentana={"id":id, "idPadre": idPadre}
		var i= this.indiceVentana(id)
		if (i==-1)
			this.lventanas[this.lventanas.length]=nuevaVentana
		else
			this.lventanas[i]=nuevaVentana
		}

	/* + saca(id) */
	this.saca=function (id)	{
		//Tengo que arreglar los idPadre de los hijos si se da el caso
		//Por cada hijo cuyo idPadre sea el id, ya que se van a quedar huerfanos les doy el id de su "abuelo"		
		var i=this.indiceVentana(id)
		if (i==-1)
			return
		var elIdPadre=this.lventanas[i].idPadre
		for (var r=0;r<this.lventanas.length; r++)
			if (this.lventanas[r].idPadre==id)
				this.lventanas[r].idPadre=elIdPadre
		//Regenero el array 
		var nuevoArrVent=[];
		for (var r=0;r<this.lventanas.length; r++)
			if (this.lventanas[r].id!=id)
				nuevoArrVent[nuevoArrVent.length]=this.lventanas[r]
		this.lventanas=nuevoArrVent
		}
		
	/* + getVentana(id) */
	this.getVentana=function (id)	{
		var i= this.indiceVentana(id)
		if (i==-1)
			return null
		else
			return this.lventanas[i]
		}


	/* + getlista() */
	this.getLista=function ()	{
		return this.lventanas
		}

	/* + existe(id) */
	this.existe=function (id)	{
		if (this.indiceVentana(id)==-1)
			return false
		else
			return true
		}
		
	this.indiceVentana=function (id)	{
		for (var r=0;r<this.lventanas.length;r++)
			if (this.lventanas[r].id == id)
				return r
		return -1
		}
		
	this.sonFamilia=function (id1,id2)	{
		if (this.descendienteDe(id1,id2))
			return true
		if (this.descendienteDe(id2,id1))
			return true
		return false
		}
		
	this.descendienteDe=function (id1,id2)	{
		//Verifica si la ventana con id=id2 desciende de la de id=id1
		var v2=this.getVentana(id2);	
		if (v2==null)
			return false
		var unIdPadre=v2.idPadre
		while (unIdPadre!=null)	{
			if (unIdPadre==id1)
				return true
			unIdPadre=this.getVentana(unIdPadre).idPadre
			}
		return false
		}		
	}		
	
function drExtraeExtension(rutaCompleta)	{
	var i=rutaCompleta.lastIndexOf('.');
	if (i==-1)
		return ""
	else	
		return rutaCompleta.substr(i+1);
	}	